/*

 Copyright (C) 2009-2011 Oleksandr Natalenko aka post-factum

 This program is free software; you can redistribute it and/or modify
 it under the terms of the Universal Program License as published by
 Oleksandr Natalenko aka post-factum; see file COPYING for details.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 You should have received a copy of the Universal Program
 License along with this program; if not, write to
 pfactum@gmail.com

*/

package channel;

import modulation.ModulatorSignal;

import java.util.ArrayList;
import java.util.List;

/**
 * Model of transmission channel with Gaussian noise
 *
 * @author Oleksandr Natalenko aka post-factum
 */
public class Channel {
    private List<ModulatorSignal> inputModulatorSignals;
    private List<NoiseSignal> inputNoiseSignals;
    private List<PropagatorSignal> delayedPropagatorSignals;

    /**
     * Creates channel with given signals on its input
     *
     * @param _inputModulatorSignals list of input signals from modulator
     * @param _inputNoiseSignals     list of input signals from noise generator
     */
    public Channel(List<ModulatorSignal> _inputModulatorSignals, List<NoiseSignal> _inputNoiseSignals) {
        inputModulatorSignals = _inputModulatorSignals;
        inputNoiseSignals = _inputNoiseSignals;
    }

    public void setDelayedModulatorSignals(List<PropagatorSignal> _delayedModulatorSignals) {
        if (_delayedModulatorSignals.size() != inputModulatorSignals.size()) {
            List<PropagatorSignal> result = new ArrayList<PropagatorSignal>();
            for (int i = 0; i < inputModulatorSignals.size(); i++) {
                ModulatorSignal modulatorSignal = inputModulatorSignals.get(i);
                PropagatorSignal delayedSignal0 = _delayedModulatorSignals.get(i);
                PropagatorSignal delayedSignal1 = _delayedModulatorSignals.get(i + 1);
                PropagatorSignal resulting = new PropagatorSignal(modulatorSignal.getStart(), modulatorSignal.getEnd());
                resulting.setdAmplitude0(delayedSignal0.getAmplitude());
                resulting.setdAmplitude1(delayedSignal1.getAmplitude());
                resulting.setdFrequency0(delayedSignal0.getFrequency());
                resulting.setdFrequency1(delayedSignal1.getFrequency());
                resulting.setdPhase0(delayedSignal0.getPhase());
                resulting.setdPhase1(delayedSignal1.getPhase());
                resulting.setdStart0(delayedSignal0.getStart());
                resulting.setdEnd1(delayedSignal0.getEnd());
                result.add(resulting);
            }
            this.delayedPropagatorSignals = result;
        } else {
            this.delayedPropagatorSignals = _delayedModulatorSignals;
        }
    }

    public List<PropagatorSignal> getDelayedModulatorSignals() {
        return delayedPropagatorSignals;
    }

    /**
     * Returns list of noised signals
     *
     * @return list of channel signals
     */
    public List<ChannelSignal> getSignals() {
        List<ChannelSignal> outputSignals = new ArrayList<ChannelSignal>();
        if (delayedPropagatorSignals.isEmpty()) {
            for (int k = 0; k < inputModulatorSignals.size(); k++) {
                outputSignals.add(new ChannelSignal(inputModulatorSignals.get(k), inputNoiseSignals.get(k)));
            }
        } else {
            for (int k = 0; k < inputModulatorSignals.size(); k++) {
                ChannelSignal channelSignal = new ChannelSignal(inputModulatorSignals.get(k), inputNoiseSignals.get(k));
                channelSignal.setDelayedSignal(delayedPropagatorSignals.get(k));

                outputSignals.add(channelSignal);
            }
        }
        return outputSignals;
    }

}
